import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GUI } from "three/examples/jsm/libs/dat.gui.module";
import { RepeatWrapping } from "three/src/constants";
import {
  PerspectiveCamera,
  Scene,
  WebGLRenderer,
  Mesh,
  BoxBufferGeometry,
  MeshBasicMaterial,
  TextureLoader,
  OrthographicCamera,
  Texture,
  Vector2,
} from "three";

let camera: PerspectiveCamera, scene: Scene, renderer: WebGLRenderer;
let mesh: Mesh;
let material: MeshBasicMaterial;
let texture: Texture;
let control: OrbitControls;
let gui: GUI;
const API = {
  offsetX: 0,
  offsetY: 0,
  repeatX: 0.25,
  repeatY: 0.25,
  rotation: 0,
  centerX: 0.5,
  centerY: 0.5,
};

init();
animate();

function init() {
  let aspect = window.innerWidth / window.innerHeight;
  let frustumSize = 600;

  camera = new PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    1000
  );
  camera.position.z = 30;
  renderer = new WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  scene = new Scene();

  let geometry = new BoxBufferGeometry(10, 10, 10);
  texture = new TextureLoader().load(
    require("../static/images/uv_grid_opengl.jpg").default
  );
  texture.wrapS = texture.wrapT = RepeatWrapping;
  texture.anisotropy = renderer.capabilities.getMaxAnisotropy();

  material = new MeshBasicMaterial({
    map: texture,
  });
  mesh = new Mesh(geometry, material);
  scene.add(mesh);

  updateTransform();
  initGUI();
  control = new OrbitControls(camera, renderer.domElement);
  // renderer.render(scene, camera);
}

function initGUI() {
  gui = new GUI();

  gui.add(API, "offsetX", 0.0, 1.0).onChange(updateTransform);
  gui.add(API, "offsetY", 0.0, 1.0).onChange(updateTransform);
  gui.add(API, "centerX", 0.0, 1.0).onChange(updateTransform);
  gui.add(API, "centerY", 0.0, 1.0).onChange(updateTransform);
  gui.add(API, "repeatX", 0.25, 2.0).onChange(updateTransform);
  gui.add(API, "repeatY", 0.25, 2.0).onChange(updateTransform);
  gui.add(API, "rotation", -2.0, 2.0).onChange(updateTransform);
}

function updateTransform() {
  texture.offset.set(API.offsetX, API.offsetY);
  texture.repeat.set(API.repeatX, API.repeatY);
  texture.center.set(API.centerX, API.centerY);
  texture.rotation = API.rotation;
}

function animate() {
  requestAnimationFrame(animate);

  renderer.render(scene, camera);
}
